knitr::opts_chunk$set(echo = TRUE) 
library(reticulate)
use_python("/Users/oldemarrodriguez/anaconda3/bin/python3.7") # PROMIDAT
# use_python("/anaconda3/bin/python3.6") ## Portátil

Clustering Jerárquico

import os
import pandas as pd
import numpy as np
from   math import pi
from   sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
# Import the dendrogram function and the ward, single, complete, average, linkage and fcluster clustering function from SciPy
from scipy.cluster.hierarchy import dendrogram, ward, single, complete,average,linkage, fcluster
from scipy.spatial.distance import pdist

Para mostrar un gráfico en un archivo rmd use show() y close()

def open_close_plot():
    plt.show()
    plt.close()

Funciones para graficar Bar-plot y Radar-Plot para las interpretaciones

Función para calcular los centroides de cada cluster

def centroide(num_cluster, datos, clusters):
  ind = clusters == num_cluster
  return(pd.DataFrame(datos[ind].mean()).T)

Función para graficar los gráficos de Barras para la interpretación de clústeres

def bar_plot(centros, labels, cluster = None, var = None):
    from seaborn import color_palette
    colores = color_palette()
    def inside_plot(valores, labels, titulo):
        plt.barh(range(len(valores)), valores, 1/1.5, color = colores)
        plt.title(titulo)
    if var is not None:
        centros = np.array([n[[x in var for x in labels]] for n in centros])
        colores = [colores[x % len(colores)] for x, i in enumerate(labels) if i in var]
        labels = labels[[x in var for x in labels]]
    if cluster is None:
        for i in range(centros.shape[0]):
            plt.subplot(1, centros.shape[0], i + 1)
            inside_plot(centros[i].tolist(), labels, ('Cluster ' + str(i)))
            plt.yticks(range(len(labels)), labels) if i == 0 else plt.yticks([]) 
    else:
        pos = 1
        for i in cluster:
            plt.subplot(1, len(cluster), pos)
            inside_plot(centros[i].tolist(), labels, ('Cluster ' + str(i)))
            plt.yticks(range(len(labels)), labels) if pos == 1 else plt.yticks([]) 
            pos += 1

Función para graficar los gráficos tipo Radar para la interpretación de clústeres

def radar_plot(centros, labels):
    from math import pi
    centros = np.array([((n - min(n)) / (max(n) - min(n)) * 100) if 
                        max(n) != min(n) else (n/n * 50) for n in centros.T])
    angulos = [n / float(len(labels)) * 2 * pi for n in range(len(labels))]
    angulos += angulos[:1]
    ax = plt.subplot(111, polar = True)
    ax.set_theta_offset(pi / 2)
    ax.set_theta_direction(-1)
    
    plt.xticks(angulos[:-1], labels)
    ax.set_rlabel_position(0)
    plt.yticks([10, 20, 30, 40, 50, 60, 70, 80, 90, 100],
           ["10%", "20%", "30%", "40%", "50%", "60%", "70%", "80%", "90%", "100%"], 
           color = "grey", size = 8)
    plt.ylim(-10, 100)
    for i in range(centros.shape[1]):
        valores = centros[:, i].tolist()
        valores += valores[:1]
        ax.plot(angulos, valores, linewidth = 1, linestyle = 'solid', 
                label = 'Cluster ' + str(i))
        ax.fill(angulos, valores, alpha = 0.3)
    plt.legend(loc='upper right', bbox_to_anchor = (0.1, 0.1))

Ejemplo Datos de Estudiantes

os.chdir("/Users/oldemarrodriguez/Google Drive/MDCurso/Datos")
datos = pd.read_csv('EjemploEstudiantes.csv',delimiter=';',decimal=",",index_col=0)
print(datos)
        Matematicas  Ciencias  Espanol  Historia  EdFisica
Lucia           7.0       6.5      9.2       8.6       8.0
Pedro           7.5       9.4      7.3       7.0       7.0
Ines            7.6       9.2      8.0       8.0       7.5
Luis            5.0       6.5      6.5       7.0       9.0
Andres          6.0       6.0      7.8       8.9       7.3
Ana             7.8       9.6      7.7       8.0       6.5
Carlos          6.3       6.4      8.2       9.0       7.2
Jose            7.9       9.7      7.5       8.0       6.0
Sonia           6.0       6.0      6.5       5.5       8.7
Maria           6.8       7.2      8.7       9.0       7.0

Ejemplos con varias Funciones de Agregación

ward_res = ward(datos)         #Ward
single_res = single(datos)     #Salto mínimo
complete_res = complete(datos) #Salto Máximo
average_res = average(datos)   #Promedio
dendrogram(average_res,labels= datos.index.tolist())
open_close_plot()

plt.figure(figsize=(13,10))
dendrogram(complete_res,labels= datos.index.tolist())
open_close_plot()

plt.figure(figsize=(13,10))
dendrogram(single_res,labels= datos.index.tolist())
open_close_plot()

plt.figure(figsize=(13,10))
dendrogram(ward_res,labels= datos.index.tolist())

Agrega cortes con 2 y 3 clústeres con agregación de Ward

ax = plt.gca()
limites = ax.get_xbound()
ax.plot(limites, [7.25, 7.25], '--', c='k')
ax.plot(limites, [4, 4], '--', c='k')
ax.text(limites[1], 7.25, ' dos clústeres', va='center', fontdict={'size': 15})
ax.text(limites[1], 4, ' tres clústeres', va='center', fontdict={'size': 15})
plt.xlabel("Orden en el eje X")
plt.ylabel("Distancia o Agregación")
open_close_plot()

Interpretación con 3 clústeres

Gráfico de Barras con Ward

grupos = fcluster(linkage(pdist(datos), method = 'ward', metric='euclidean'), 3, criterion = 'maxclust')
grupos = grupos-1 # Se resta 1 para que los clústeres se enumeren de 0 a (K-1), como usualmente lo hace Python
# El siguiente print es para ver en qué cluster quedó cada individuo
print(grupos)
[2 0 0 1 2 0 2 0 1 2]
centros = np.array(pd.concat([centroide(0, datos, grupos), 
                              centroide(1, datos, grupos),
                              centroide(2, datos, grupos)]))
print(centros)    
[[7.7   9.475 7.625 7.75  6.75 ]
 [5.5   6.25  6.5   6.25  8.85 ]
 [6.525 6.525 8.475 8.875 7.375]]
plt.figure(1, figsize = (12, 8))
bar_plot(centros, datos.columns)
open_close_plot()

Gráfico Radar plot con Ward

grupos = fcluster(linkage(pdist(datos), method = 'ward', metric='euclidean'), 3, criterion = 'maxclust')
grupos = grupos-1 # Se resta 1 para que los clústeres se enumeren de 0 a (K-1), como usualmente lo hace Python
# El siguiente print es para ver en qué cluster quedó cada individuo
print(grupos)
[2 0 0 1 2 0 2 0 1 2]
centros = np.array(pd.concat([centroide(0, datos, grupos), 
                              centroide(1, datos, grupos),
                              centroide(2, datos, grupos)]))
print(centros)
[[7.7   9.475 7.625 7.75  6.75 ]
 [5.5   6.25  6.5   6.25  8.85 ]
 [6.525 6.525 8.475 8.875 7.375]]
plt.figure(1, figsize = (10, 10))
radar_plot(centros, datos.columns)
open_close_plot()

Códigos Dummy (Códigos Disyuntivos Completos) - pd.get_dummies(Datos)

os.chdir("/Users/oldemarrodriguez/Google Drive/MDCurso/Datos")
datos = pd.read_csv('EjemploEstudiantes_Categoricas.csv',delimiter=';',decimal=",",index_col=0)
print(datos.head())
        Matematicas  Ciencias  Espanol   ...     EdFisica  Genero Conducta
Lucia           7.0       6.5      9.2   ...          8.0       F        3
Pedro           7.5       9.4      7.3   ...          7.0       M        2
Ines            7.6       9.2      8.0   ...          7.5       F        2
Luis            5.0       6.5      6.5   ...          9.0       M        1
Andres          6.0       6.0      7.8   ...          7.3       M        2

[5 rows x 7 columns]
print(datos.shape)
(10, 7)
print(datos.dtypes)
Matematicas    float64
Ciencias       float64
Espanol        float64
Historia       float64
EdFisica       float64
Genero          object
Conducta         int64
dtype: object

Recodificando la variable “Conducta” usando texto y luego se convierten a variables Dummy

def recodificar(col, nuevo_codigo):
  col_cod = pd.Series(col, copy=True)
  for llave, valor in nuevo_codigo.items():
    col_cod.replace(llave, valor, inplace=True)
  return col_cod
datos["Conducta"] = recodificar(datos["Conducta"], {1:'Mala',2:'Regular',3:'Buena'})
print(datos.head())
        Matematicas  Ciencias  Espanol   ...     EdFisica  Genero Conducta
Lucia           7.0       6.5      9.2   ...          8.0       F    Buena
Pedro           7.5       9.4      7.3   ...          7.0       M  Regular
Ines            7.6       9.2      8.0   ...          7.5       F  Regular
Luis            5.0       6.5      6.5   ...          9.0       M     Mala
Andres          6.0       6.0      7.8   ...          7.3       M  Regular

[5 rows x 7 columns]
print(datos.dtypes)
# Conviertiendo la variables en Dummy
Matematicas    float64
Ciencias       float64
Espanol        float64
Historia       float64
EdFisica       float64
Genero          object
Conducta        object
dtype: object
datos_dummy = pd.get_dummies(datos)
print(datos_dummy.head())
        Matematicas  Ciencias        ...         Conducta_Mala  Conducta_Regular
Lucia           7.0       6.5        ...                     0                 0
Pedro           7.5       9.4        ...                     0                 1
Ines            7.6       9.2        ...                     0                 1
Luis            5.0       6.5        ...                     1                 0
Andres          6.0       6.0        ...                     0                 1

[5 rows x 10 columns]
print(datos_dummy.dtypes)
Matematicas         float64
Ciencias            float64
Espanol             float64
Historia            float64
EdFisica            float64
Genero_F              uint8
Genero_M              uint8
Conducta_Buena        uint8
Conducta_Mala         uint8
Conducta_Regular      uint8
dtype: object
ward_res = ward(datos_dummy)         # Ward
dendrogram(ward_res,labels= datos_dummy.index.tolist())

Agrega cortes con 2 y 3 clústeres con agregación de Ward

ax = plt.gca()
limites = ax.get_xbound()
ax.plot(limites, [7, 7], '--', c='k')
ax.plot(limites, [4, 4], '--', c='k')
ax.text(limites[1], 7, ' dos clústeres', va='center', fontdict={'size': 15})
ax.text(limites[1], 4, ' tres clústeres', va='center', fontdict={'size': 15})
plt.xlabel("Orden en el eje X")
plt.ylabel("Distancia o Agregación")
open_close_plot()

Interpretación con 3 clústeres

Gráfico de Barras con Ward

grupos = fcluster(linkage(pdist(datos_dummy), method = 'ward', metric='binary'), 3, criterion = 'maxclust')
grupos = grupos-1 # Se resta 1 para que los clústeres se enumeren de 0 a (K-1), como usualmente lo hace Python
# El siguiente print es para ver en qué cluster quedó cada individuo
print(grupos)
[2 0 0 1 2 0 2 0 1 2]
centros = np.array(pd.concat([centroide(0, datos_dummy, grupos), 
                              centroide(1, datos_dummy, grupos),
                              centroide(2, datos_dummy, grupos)]))
print(centros)    
[[7.7   9.475 7.625 7.75  6.75  0.5   0.5   0.25  0.25  0.5  ]
 [5.5   6.25  6.5   6.25  8.85  0.5   0.5   0.    0.5   0.5  ]
 [6.525 6.525 8.475 8.875 7.375 0.5   0.5   0.5   0.25  0.25 ]]
plt.figure(1, figsize = (12, 8))
bar_plot(centros, datos_dummy.columns)
open_close_plot()

Gráfico Radar plot con Ward

grupos = fcluster(linkage(pdist(datos_dummy), method = 'ward', metric='binary'), 3, criterion = 'maxclust')
grupos = grupos-1 # Se resta 1 para que los clústeres se enumeren de 0 a (K-1), como usualmente lo hace Python
# El siguiente print es para ver en qué cluster quedó cada individuo
print(grupos)
[2 0 0 1 2 0 2 0 1 2]
centros = np.array(pd.concat([centroide(0, datos_dummy, grupos), 
                              centroide(1, datos_dummy, grupos),
                              centroide(2, datos_dummy, grupos)]))
print(centros)
[[7.7   9.475 7.625 7.75  6.75  0.5   0.5   0.25  0.25  0.5  ]
 [5.5   6.25  6.5   6.25  8.85  0.5   0.5   0.    0.5   0.5  ]
 [6.525 6.525 8.475 8.875 7.375 0.5   0.5   0.5   0.25  0.25 ]]
plt.figure(1, figsize = (10, 10))
radar_plot(centros, datos_dummy.columns)
open_close_plot()

Ejemplo con los datos Iris

os.chdir("/Users/oldemarrodriguez/Google Drive/MDCurso/Datos")
datos = pd.read_csv('iris.csv',delimiter=';',decimal=".")
datos = datos.iloc[:,:4] #Elimina la variable categorica
print(datos.head())
   s.largo  s.ancho  p.largo  p.ancho
0      5.1      3.5      1.4      0.2
1      4.9      3.0      1.4      0.2
2      4.7      3.2      1.3      0.2
3      4.6      3.1      1.5      0.2
4      5.0      3.6      1.4      0.2
print(datos.shape)
(150, 4)
ward_res = ward(datos)         #Ward
single_res = single(datos)     #Salto mínimo
complete_res = complete(datos) #Salto Máximo
average_res = average(datos)   #Promedio
dendrogram(average_res,labels= datos.index.tolist(),color_threshold=1.9)
open_close_plot()

plt.figure(figsize=(13,10))
dendrogram(complete_res,labels= datos.index.tolist(),color_threshold=3.5)
open_close_plot()

plt.figure(figsize=(13,10))
dendrogram(single_res,labels= datos.index.tolist(),color_threshold=0.7)
open_close_plot()

plt.figure(figsize=(13,10))
dendrogram(ward_res,labels= datos.index.tolist(),color_threshold=8)

Agrega cortes con 2 y 3 clústeres al Dendograma con Ward

ax = plt.gca()
limites = ax.get_xbound()
ax.plot(limites, [20, 20], '--', c='k')
ax.plot(limites, [8, 8], '--', c='k')
ax.text(limites[1], 20, ' dos clústeres', va='center', fontdict={'size': 15})
ax.text(limites[1], 8, ' tres clústeres', va='center', fontdict={'size': 15})
plt.xlabel("Orden en el eje X")
plt.ylabel("Distancia o Agregación")
open_close_plot()

Interpretación con 3 clústeres

Gráfico de Barras con Ward

grupos = fcluster(linkage(pdist(datos), method = 'ward'), 3, criterion = 'maxclust')
grupos = grupos-1 # Se resta 1 para que los clústeres se enumeren de 0 a (K-1), como usualmente lo hace Python
# El siguiente print es para ver en qué cluster quedó cada individuo
print(grupos)
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 1 1 1 2 1 1 1 1
 1 1 2 2 1 1 1 1 2 1 2 1 2 1 1 2 2 1 1 1 1 1 2 2 1 1 1 2 1 1 1 2 1 1 1 2 1
 1 2]
centros = np.array(pd.concat([centroide(0, datos, grupos), 
                              centroide(1, datos, grupos),
                              centroide(2, datos, grupos)]))
print(centros)    
[[5.006      3.418      1.464      0.244     ]
 [6.86944444 3.08611111 5.76944444 2.10555556]
 [5.9203125  2.7515625  4.4203125  1.434375  ]]
plt.figure(1, figsize = (12, 8))
bar_plot(centros, datos.columns)
open_close_plot()

Gráfico Radar plot con Ward

grupos = fcluster(linkage(pdist(datos), method = 'ward'), 3, criterion = 'maxclust')
grupos = grupos-1 # Se resta 1 para que los clústeres se enumeren de 0 a (K-1), como usualmente lo hace Python
# El siguiente print es para ver en qué cluster quedó cada individuo
print(grupos)
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 1 1 1 2 1 1 1 1
 1 1 2 2 1 1 1 1 2 1 2 1 2 1 1 2 2 1 1 1 1 1 2 2 1 1 1 2 1 1 1 2 1 1 1 2 1
 1 2]
centros = np.array(pd.concat([centroide(0, datos, grupos), 
                              centroide(1, datos, grupos),
                              centroide(2, datos, grupos)]))
print(centros)
[[5.006      3.418      1.464      0.244     ]
 [6.86944444 3.08611111 5.76944444 2.10555556]
 [5.9203125  2.7515625  4.4203125  1.434375  ]]
plt.figure(1, figsize = (10, 10))
radar_plot(centros, datos.columns)
open_close_plot()

Gráfico de Barras con Single

grupos = fcluster(linkage(pdist(datos), method = 'single'), 3, criterion = 'maxclust')
grupos = grupos-1 # Se resta 1 para que los clústeres se enumeren de 0 a (K-1), como usualmente lo hace Python
# El siguiente print es para ver en qué cluster quedó cada individuo
print(grupos)
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2]
centros = np.array(pd.concat([centroide(0, datos, grupos), 
                              centroide(1, datos, grupos),
                              centroide(2, datos, grupos)]))
print(centros)   
[[5.006      3.418      1.464      0.244     ]
 [7.8        3.8        6.55       2.1       ]
 [6.23061224 2.85306122 4.87244898 1.66734694]]
plt.figure(1, figsize = (12, 8))
bar_plot(centros, datos.columns)
open_close_plot()

Gráfico Radar plot con Single

grupos = fcluster(linkage(pdist(datos), method = 'single'), 3, criterion = 'maxclust')
grupos = grupos-1 # Se resta 1 para que los clústeres se enumeren de 0 a (K-1), como usualmente lo hace Python
# El siguiente print es para ver en qué cluster quedó cada individuo
print(grupos)
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2]
centros = np.array(pd.concat([centroide(0, datos, grupos), 
                              centroide(1, datos, grupos),
                              centroide(2, datos, grupos)]))
print(centros)
[[5.006      3.418      1.464      0.244     ]
 [7.8        3.8        6.55       2.1       ]
 [6.23061224 2.85306122 4.87244898 1.66734694]]
plt.figure(1, figsize = (10, 10))
radar_plot(centros, datos.columns)
open_close_plot()

Ejemplo datos de servicio al cliente

os.chdir("/Users/oldemarrodriguez/Google Drive/MDCurso/Datos")
datos = pd.read_csv('EjemploClientesCorregidaEdad.csv',delimiter=';',decimal=",",index_col=0)
print(datos.head())
                Edad/10        ...         Calidad Servicio
Nombre Cliente                 ...                         
 Ariana             2.5        ...                      6.6
 Guiselle           2.4        ...                      5.4
 Francisco          2.8        ...                      8.5
 Griselda           2.3        ...                      5.4
 Damaris            4.9        ...                      3.3

[5 rows x 12 columns]
print(datos.shape)
(37, 12)
ward_res = ward(datos)         #Ward
single_res = single(datos)     #Salto mínimo
complete_res = complete(datos) #Salto Máximo
average_res = average(datos)   #Promedio
dendrogram(average_res,labels= datos.index.tolist(),color_threshold=9.8)
open_close_plot()

plt.figure(figsize=(13,10))
dendrogram(complete_res,labels= datos.index.tolist(),color_threshold=13)
open_close_plot()

plt.figure(figsize=(13,10))
dendrogram(single_res,labels= datos.index.tolist(),color_threshold=6.5)
open_close_plot()

plt.figure(figsize=(13,10))
dendrogram(ward_res,labels= datos.index.tolist(),color_threshold=15)

Agrega cortes con 2 y 3 clústeres con agregación de Ward

ax = plt.gca()
limites = ax.get_xbound()
ax.plot(limites, [20, 20], '--', c='k')
ax.plot(limites, [15, 15], '--', c='k')
ax.plot(limites, [12.5, 12.5], '--', c='k')
ax.text(limites[1], 20, ' dos clústeres', va='center', fontdict={'size': 15})
ax.text(limites[1], 15, ' tres clústeres', va='center', fontdict={'size': 15})
ax.text(limites[1], 12.5, ' cinco clústeres', va='center', fontdict={'size': 15})
plt.xlabel("Orden en el eje X")
plt.ylabel("Distancia o Agregación")
open_close_plot()

Interpretación con 2 clústeres

Gráfico de Barras con Ward

grupos = fcluster(linkage(pdist(datos), method = 'ward'), 2, criterion = 'maxclust')
grupos = grupos-1 # Se resta 1 para que los clústeres se enumeren de 0 a (K-1), como usualmente lo hace Python
# El siguiente print es para ver en qué cluster quedó cada individuo
print(grupos)
[1 1 1 0 0 0 1 0 0 1 1 1 1 1 1 0 1 1 1 0 1 1 0 0 0 1 0 1 1 1 1 1 1 0 0 1 1]
centros = np.array(pd.concat([centroide(0, datos, grupos), 
                              centroide(1, datos, grupos)]))
print(centros)   
[[3.03846154 2.69230769 5.44615385 7.38461538 4.69230769 9.69230769
  2.13846154 9.01538462 5.84615385 5.83076923 5.30769231 5.3       ]
 [2.79583333 3.58333333 6.48333333 8.175      7.53333333 9.61666667
  4.05416667 8.99166667 7.14166667 7.4        8.03333333 5.00416667]]
plt.figure(1, figsize = (12, 8))
bar_plot(centros, datos.columns)
open_close_plot()

Gráfico Radar plot con Ward

grupos = fcluster(linkage(pdist(datos), method = 'ward'), 2, criterion = 'maxclust')
grupos = grupos-1 # Se resta 1 para que los clústeres se enumeren de 0 a (K-1), como usualmente lo hace Python
# El siguiente print es para ver en qué cluster quedó cada individuo
print(grupos)
[1 1 1 0 0 0 1 0 0 1 1 1 1 1 1 0 1 1 1 0 1 1 0 0 0 1 0 1 1 1 1 1 1 0 0 1 1]
centros = np.array(pd.concat([centroide(0, datos, grupos), 
                              centroide(1, datos, grupos)]))
print(centros)
[[3.03846154 2.69230769 5.44615385 7.38461538 4.69230769 9.69230769
  2.13846154 9.01538462 5.84615385 5.83076923 5.30769231 5.3       ]
 [2.79583333 3.58333333 6.48333333 8.175      7.53333333 9.61666667
  4.05416667 8.99166667 7.14166667 7.4        8.03333333 5.00416667]]
plt.figure(1, figsize = (10, 10))
radar_plot(centros, datos.columns)
open_close_plot()

Gráfico de Barras con Single

grupos = fcluster(linkage(pdist(datos), method = 'single'), 2, criterion = 'maxclust')
grupos = grupos-1 # Se resta 1 para que los clústeres se enumeren de 0 a (K-1), como usualmente lo hace Python
# El siguiente print es para ver en qué cluster quedó cada individuo
print(grupos)
[0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
centros = np.array(pd.concat([centroide(0, datos, grupos), 
                              centroide(1, datos, grupos)]))
print(centros)    
[[ 2.87222222  3.          6.17222222  7.9         6.50555556  9.63333333
   3.43888889  8.98333333  6.66666667  6.86111111  7.07777778  5.14166667]
 [ 3.2        13.          4.2         7.8         7.6        10.
   1.3         9.6         7.4         6.4         7.          3.9       ]]
plt.figure(1, figsize = (12, 8))
bar_plot(centros, datos.columns)
open_close_plot()

Gráfico Radar plot con Single

grupos = fcluster(linkage(pdist(datos), method = 'single'), 2, criterion = 'maxclust')
grupos = grupos-1 # Se resta 1 para que los clústeres se enumeren de 0 a (K-1), como usualmente lo hace Python
# El siguiente print es para ver en qué cluster quedó cada individuo
print(grupos)
[0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
centros = np.array(pd.concat([centroide(0, datos, grupos), 
                              centroide(1, datos, grupos)]))
print(centros)
[[ 2.87222222  3.          6.17222222  7.9         6.50555556  9.63333333
   3.43888889  8.98333333  6.66666667  6.86111111  7.07777778  5.14166667]
 [ 3.2        13.          4.2         7.8         7.6        10.
   1.3         9.6         7.4         6.4         7.          3.9       ]]
plt.figure(1, figsize = (10, 10))
radar_plot(centros, datos.columns)
open_close_plot()